package com.nakaikensuke.SNE;

/**
Copyright (c) 2011-2012, KENSUKE NAKAI
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list
  of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
  list of conditions and the following disclaimer in the documentation and/or
  other materials provided with the distribution.
* Neither the name of the nakaikensuke.com nor the names of its contributors may
  be used to endorse or promote products derived from this software without
  specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

import java.io.File;
import java.util.HashMap;
import java.util.List;

import com.yohpapa.tools.MimeUtils;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.widget.ImageView;

public class IconManager {
	
	private static HashMap<String, Drawable> _caches;
	private static Drawable _defaultIcon;
	
	public static void initialize(Context context) {
		_caches = new HashMap<String, Drawable>();
		_defaultIcon = context.getResources().getDrawable(R.drawable.file_icon);
	}
	
	public static synchronized Drawable getIconFromCache(String fileName) {
		
		// MIME種別が特定できなければデフォルトとする
		String mime = MimeUtils.getMimeType(fileName);
		if(mime == null)
			return _defaultIcon;
		
		// キャッシュにない場合はなかったことを示すnullを返す
		if(!_caches.containsKey(mime))
			return null;
		
		// キャッシュからアイコン取得
		return _caches.get(mime);
	}
	
	public static synchronized void setIconToCache(String mime, Drawable icon) {
		_caches.put(mime, icon);
	}
	
	public static void getIconAsync(Context context, ImageView iconView, String fullPath) {
		IconTask task = new IconTask(iconView, context);
		task.execute(fullPath);
	}
	
	private static class IconTask extends AsyncTask<String, Void, Drawable> {

		private final ImageView _iconView;
		private final int _tag;
		private final Object _lock;
		private final PackageManager _manager;
		
		public IconTask(ImageView iconView, Context context) {
			_iconView = iconView;
			_tag = (Integer)iconView.getTag();
			_manager = context.getPackageManager();
			_lock = context;
		}
		
		@Override
		protected Drawable doInBackground(String... params) {
			
			// ファイル名とMIME種別を取得しておく
			String fullPath = params[0];
			String fileName = new File(fullPath).getName();
			String mimeType = MimeUtils.getMimeType(fileName);
			
			synchronized (_lock) {
				Drawable icon = null;
				try {
					// 何はともあれキャッシュにアイコンがないかチェック
					icon = getIconFromCache(fileName);
					if(icon != null)
						return icon;
					
					// もしなければパッケージマネージャから対応するアプリの一覧を取得
					Intent intent = new Intent();
					intent.setAction(Intent.ACTION_VIEW);
					Uri uri = Uri.fromFile(new File(fullPath));
					intent.setDataAndType(uri, mimeType);
	
					List<ResolveInfo> list = _manager.queryIntentActivities(
	                                        intent,
	                                        PackageManager.MATCH_DEFAULT_ONLY);
					if(list == null || list.size() <= 0) {
						icon = _defaultIcon;
						return icon;
					}
					
					// 一番目のアプリのアイコンを取得
					icon = list.get(0).loadIcon(_manager);
					return icon;
					
				} finally {
					// 取得したアイコンをキャッシュに登録
					IconManager.setIconToCache(mimeType, icon);
				}
			}
		}

		@Override
		protected void onPostExecute(Drawable result) {
			
			// タグがまだ一致していればアイコンを設定する
			if(_tag != (Integer)_iconView.getTag())
				return;
			
			_iconView.setImageDrawable(result);
		}
	}
}
